package com.gaofei.activiti.controller;

import com.gaofei.activiti.pojo.ActivitiVo;
import com.gaofei.activiti.pojo.UserTask;
import com.gaofei.activiti.service.LeaveService;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
@RequestMapping("v2")
@Slf4j
public class QingjV2Controller {

    @Autowired
    TaskService taskService;

    @Autowired
    RuntimeService runtimeService;

    @Autowired
    HistoryService historyService;

    @Autowired
    RepositoryService repositoryService;


    @Autowired
    LeaveService leaveService;


    //审核
    @RequestMapping("completeUserTaskById")
    public Object completeUserTaskById(@RequestBody ActivitiVo activitiVo) {
        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("holiday", activitiVo.getHoliday());//流程变量
        taskService.complete(activitiVo.getTaskId(), objectObjectHashMap);//完成任务
        return "success";
    }

    //查询待办任务
    @RequestMapping("queryUserTaskByUserName")
    public Object queryTask(@RequestBody ActivitiVo activitiVo) {

        List<UserTask> list = new ArrayList<>();
        ;

        List<Task> tasksList = taskService.createTaskQuery()
                .processDefinitionKey("qingjiav2") //流程Key
                .taskAssignee(activitiVo.getUsername())//只查询该任务负责人的任务
                .list();
        for (Task task : tasksList) {
            //根据任务ID获取当前流程实例
            Map<String, Object> taskMap = new HashMap<>();
            taskMap.put("id", task.getId());
            taskMap.put("name", task.getName());
            taskMap.put("assignee", task.getAssignee());
            taskMap.put("description", task.getDescription());
            taskMap.put("processDefinitionId", task.getProcessDefinitionId());
            taskMap.put("processInstanceId", task.getProcessInstanceId());
            taskMap.put("parentTaskId", task.getParentTaskId());
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();

//            String businessKey = historicProcessInstance.getBusinessKey();
//            //businessKey就是业务表的主键
//            //根据这个主键查询业务表的数据封装到map
//            Leave leave = leaveService.findLeaveById(businessKey);
//            //把leave中的数据封装进taskMap,返回给前端

            UserTask userTask = new UserTask(taskMap, historicProcessInstance);
            list.add(userTask);
        }

        return list;
    }


    /**
     * 开启流程实例啊
     *
     * @param activitiVo
     * @return
     */
    @RequestMapping("askForLeave")
    public String askForBiz(@RequestBody ActivitiVo activitiVo) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("username", activitiVo.getUsername());
        map.put("holiday", activitiVo.getHoliday());

        activitiVo.setBegin_time(new Date());
        activitiVo.setEnd_time(new Date());
        //2.把请假表单数据存储到业务表leave表中
        leaveService.save(activitiVo);
        //2.1 新增之后的主键就会返回来,封装进activitiVo
        //把业务表的主键作为流程实例的业务key  businessKey
        String businessKey = activitiVo.getId() + "";
        //3、根据流程定义Id启动流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjiav2", businessKey, map);
        System.out.println("流程定义id：" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例id：" + processInstance.getId());
        System.out.println("当前活动Id：" + processInstance.getActivityId());

        return "申请请假成功!";
    }



    //查看流程图,进度追踪
    @RequestMapping(value = "/image")
    public void lookImg(String processInstanceId, HttpServletResponse response) throws IOException, TranscoderException {
        InputStream in = this.getProcessDiagram(processInstanceId);

        //svg 转  png
        byte[] streamBytes = IOUtils.toByteArray(in);
        ByteArrayOutputStream byteArrayOutputStream = svgToPng(streamBytes);
        String imageName = "image" + Instant.now().getEpochSecond() + ".png";
//        byteArrayOutputStream.writeTo(new FileOutputStream(new File("D:/images/"+imageName)));
//        FileInputStream fis = new FileInputStream(new File("D:/images/" + imageName));
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());

        response.setContentType("text/html; charset=UTF-8");
        response.setContentType("image/png");
        response.addHeader("Content-Disposition", "inline; filename=" + imageName);
        ServletOutputStream outputStream = response.getOutputStream();
        IOUtils.copy(byteArrayInputStream, outputStream);
        outputStream.close();
    }

    //svg 转  png
    private ByteArrayOutputStream svgToPng(byte[] streamBytes) throws TranscoderException, IOException {

            PNGTranscoder t = new PNGTranscoder();

            TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(streamBytes));

            ByteArrayOutputStream ostream = new ByteArrayOutputStream();

            TranscoderOutput output = new TranscoderOutput(ostream);

            t.transcode(input, output);

            ostream.flush();
        return ostream;

    }


    /**
     * Get Process instance diagram
     */
    public InputStream getProcessDiagram(String processInstanceId) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();

        List<String> highLightedActivities = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list().stream().map(item -> item.getActivityId()).collect(Collectors.toList());

        // null check
        if (processInstance != null) {
            // get process model
            BpmnModel model = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
            if (model != null && model.getLocationMap().size() > 0) {
                ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
                // 生成流程图 已启动的task 高亮
                return generator.generateDiagram(model,
                        runtimeService.getActiveActivityIds(processInstanceId), highLightedActivities, "simsun", "simsun", "simsun");
                // 生成流程图 都不高亮
//                return generator.generateDiagram(model,Collections.<String>emptyList());
            }
        }
        return null;
    }


}
